import { onCachePageshow, getPagePath, isSupportPerformanceObserver } from '../utils/common.js'
import {lazyReportCache} from "../utils/report.js";

/**
 * FID 是衡量用户首次与页面交互时的响应时间，
 * 即从用户第一次与页面进行交互（例如点击按钮、链接、input输入等）到浏览器实际能够响应该交互之间的时间差
 * */
export default function observeFID() {
    onCachePageshow(() => {
        observeFID()
    })
    if (!isSupportPerformanceObserver()) {
        const entryHandler = (list) => {
            if (observer) {
                observer.disconnect()
            }
            
            for (const entry of list.getEntries()) {
                const json = entry.toJSON()
                json.nodeName = entry.tagName
                json.event = json.name
                json.name = json.entryType
                json.type = 'performance'
                json.pagePath = getPagePath()
                Reflect.deleteProperty(json, 'cancelable')
                lazyReportCache(json)
            }
        }
    
        const observer = new PerformanceObserver(entryHandler)
        observer.observe({ type: 'first-input', buffered: true })
        return
    }
    
    handleEventListener()
}

function handleEventListener() {
    eachEventListener(window.addEventListener)
}

function onInput(event) {
    // 仅计算可取消的事件，这些事件应触发对用户重要的行为。
    if (event.cancelable) {
        //  在某些浏览器中，`event.timeStamp`返回一个`DOMTimeStamp`值（纪元时间），而不是较新的`DOMHighResTimeStamp'（文档源时间）。
        //  为了验证这一点，我们假设任何大于1万亿的时间戳都是“DOMTimeStamp”，并使用“Date”对象而不是“performance.now（）”对其进行比较。
        // - https://github.com/GoogleChromeLabs/first-input-delay/issues/4
        const isEpochTime = event.timeStamp > 1e12
        const now = isEpochTime ? Date.now() : performance.now()
        const duration = now - event.timeStamp
        const data = {
            type: 'performance',
            subType: 'first-input',
            pagePath: getPagePath(),
            event: event.type,
            target: event.target.tagName.toLowerCase(),
            startTime: event.timeStamp,
            duration,
        }
        lazyReportCache(data)
        eachEventListener(window.removeEventListener)
    }
}


/**
 * 给事件添加监听
 * */
function eachEventListener(callback) {
    const eventList = [
        'keydown',
        'mousedown',
        'touchstart',
    ]
    eventList.forEach((type) => callback(type, onInput, { passive: true, capture: true }))
}
